/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hu.rsc.feeds.client.gui;

import hu.rsc.feeds.client.Feeds;
import hu.rsc.feeds.client.data.Category;
import hu.rsc.feeds.client.data.Dictionary;
import hu.rsc.feeds.client.data.Feed;
import hu.rsc.feeds.client.data.UserCategory;
import hu.rsc.feeds.client.data.UserFeed;
import hu.rsc.feeds.client.data.UserInfo;
import hu.rsc.feeds.client.dnd.Position;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * 
 * @author arbuckle
 */
public class SettingsPopup extends DialogBox implements ChangeHandler {
    private ListBox feedList = new ListBox();
    private ListBox langList = new ListBox();
    private ListBox langListForCat = new ListBox();
    private ListBox categoryList = new ListBox();
    private ListBox usercategoryList = new ListBox();
    private TextBox newFeedName = new TextBox();
    private TextBox newFeedUrl = new TextBox();
    private TextArea newFeedDesc = new TextArea();
    Feeds parent;

    private ListBox langListForFilter = new ListBox();
    private ListBox categoryListForFilter = new ListBox();

    public SettingsPopup(final Feeds parent) {
	super(true);
	addStyleName("body");
	this.setAnimationEnabled(true);
	this.setAutoHideEnabled(true);
	this.setText(Dictionary.getEntry(Dictionary.TITLE_SETTINGS, this));
	this.parent = parent;
	VerticalPanel main = new VerticalPanel();
	main.add(getFeedSettingsPanel());
	main.add(getNewFeedSettingsPanel());
	main.add(getCategorySettingsPanel());
	main.add(getUserCategorySettingsPanel());
	main.setStyleName("popup");
	setWidget(main);
    }

    public boolean hasThisCategory(String catname) {
	boolean has = false;
	for (Category c : this.parent.getInitData().getCategories()) {
	    if (catname.equals(c.getLabel())) {
		return true;
	    }
	}
	return has;
    }

    public boolean hasThisFeed(Long catId) {
	boolean has = false;
	for (UserFeed uc : this.parent.userFeeds.values()) {
	    if (uc.getFeed().equals(catId)) {
		return true;
	    }
	}
	return has;
    }

    public boolean hasThisUserCategory(String catname) {
	boolean has = false;
	for (UserCategory c : this.parent.getInitData().getUsercategories()) {
	    if (catname.equals(c.getLabel())) {
		return true;
	    }
	}
	return has;
    }

    public void offer() {
	if (this.newFeedName.getValue() == null || this.newFeedUrl.getValue() == null || this.newFeedName.getValue().length() < 1
		|| this.newFeedUrl.getValue().length() < 1) {
	    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_INVALID_DATAS, null));
	    return;
	}

	Long catId = null;
	try {
	    catId = Long.parseLong(this.categoryList.getValue(this.categoryList.getSelectedIndex()));
	    if (catId < 0l) {
		catId = null;
	    }
	} catch (Exception e) {
	}
	Category category = null;
	if (catId != null) {
	    for (Category cat : this.parent.getInitData().getCategories()) {
		if (cat.getId().equals(catId)) {
		    category = cat;
		}
	    }
	}

	if (category != null && !category.getLanguage().equals(this.langList.getItemText(this.langList.getSelectedIndex()))) {
	    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_DIFFERENT_LANGUAGE, null));
	}

	Feeds.getService().offer(this.newFeedName.getValue(), this.newFeedUrl.getValue(), catId, this.langList.getItemText(this.langList.getSelectedIndex()),
		this.newFeedDesc.getValue(), new AsyncCallback<Feed>() {

		    @Override
		    public void onFailure(Throwable caught) {
			Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_COMM_ERROR, null));
		    }

		    @Override
		    public void onSuccess(Feed result) {
			if (result != null) {
			    SettingsPopup.this.parent.feeds.put(result.getId(), result);
			    SettingsPopup.this.feedList.addItem(result.getLabel(), result.getId().toString());
			} else {
			    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_OFFER_ERROR, null));
			}
		    }
		});
    }

    @Override
    public void onChange(ChangeEvent event) {
	final int x = this.feedList.getElement().getAbsoluteRight() + 50;
	final int y = this.feedList.getElement().getAbsoluteTop();

	Long feedId = Long.parseLong(SettingsPopup.this.feedList.getValue(SettingsPopup.this.feedList.getSelectedIndex()));
	Feed feed = this.parent.getFeedById(feedId);

	final FeedDescriptionPopup popup = new FeedDescriptionPopup(feed, feed.getLabel());
	/*final int x = event.getNativeEvent().getClientX();
	final int y = event.getNativeEvent().getClientY();*/
	popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {

	    @Override
	    public void setPosition(int offsetWidth, int offsetHeight) {
		int left = x;
		int top = y;
		popup.setPopupPosition(left, top);
	    }
	});
    }

    private Widget getCategorySettingsPanel() {
	FlexTable main = new FlexTable();
	Label lb = new Label();
	lb.addStyleName("formtitle");
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_ADD_NEW_CATEGORY, lb));
	main.setWidget(0, 0, lb);
	main.getFlexCellFormatter().setColSpan(0, 0, 2);

	final TextBox newCatNameTb = new TextBox();

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_CATEGORY_NAME, lb));

	main.setWidget(1, 0, lb);
	main.setWidget(1, 1, newCatNameTb);

	this.langListForCat = new ListBox();
	this.langListForCat.addItem(UserInfo.LANG_EN);
	this.langListForCat.addItem(UserInfo.LANG_HU);
	if (Feeds.getLanguage().equals(UserInfo.LANG_EN)) {
	    this.langListForCat.setSelectedIndex(0);
	} else {
	    this.langListForCat.setSelectedIndex(1);
	}
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_LANG, lb));
	main.setWidget(2, 0, lb);
	main.setWidget(2, 1, this.langListForCat);

	Button addBt = new Button();
	addBt.addStyleName("button");
	addBt.setText(Dictionary.getEntry(Dictionary.BUTTON_ADD_CATEGORY, addBt));
	addBt.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		if (newCatNameTb.getValue() == null || newCatNameTb.getValue().length() == 0) {
		    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_CATEGORYNAME_REQUIRED, null));
		    return;
		}
		if (hasThisCategory(newCatNameTb.getValue())) {
		    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_CATEGORY_EXISTED, null));
		    return;
		}
		Category c = new Category();
		c.setLabel(newCatNameTb.getValue());
		c.setLanguage(SettingsPopup.this.langListForCat.getItemText(SettingsPopup.this.langListForCat.getSelectedIndex()));

		Feeds.getService().newCategory(c, new AsyncCallback<Category>() {

		    @Override
		    public void onFailure(Throwable caught) {
			Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_COMM_ERROR, null));
		    }

		    @Override
		    public void onSuccess(Category result) {
			if (result == null) {
			    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_COMM_ERROR, null));
			    return;
			}
			SettingsPopup.this.parent.getInitData().getCategories().add(result);
			if (SettingsPopup.this.langList.getItemText(SettingsPopup.this.langList.getSelectedIndex()).equals(result.getLanguage())) {
			    SettingsPopup.this.categoryList.addItem(result.getLabel(), result.getId().toString());
			    SettingsPopup.this.categoryList.setSelectedIndex(SettingsPopup.this.categoryList.getItemCount() - 1);
			}
			newCatNameTb.setValue(null);
		    }
		});
	    }
	});
	main.setWidget(3, 1, addBt);

	main.addStyleName("border");
	main.addStyleName("form");
	main.getFlexCellFormatter().addStyleName(1, 0, "formlabel");
	newCatNameTb.addStyleName("forminput");

	main.getFlexCellFormatter().addStyleName(2, 0, "formlabel");
	this.langListForCat.addStyleName("forminput");
	return main;
    }

    private Widget getFeedSettingsPanel() {
	int row = 0;
	FlexTable main = new FlexTable();

	Label lb = new Label();
	lb.addStyleName("formtitle");
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_ADD_CHANEL, lb));
	main.setWidget(row, 0, lb);
	main.getFlexCellFormatter().setColSpan(row, 0, 2);
	row++;

	this.langListForFilter = new ListBox();
	this.langListForFilter.addItem("", "-1");
	this.langListForFilter.addItem(UserInfo.LANG_EN);
	this.langListForFilter.addItem(UserInfo.LANG_HU);
	if (Feeds.getLanguage().equals(UserInfo.LANG_EN)) {
	    this.langListForFilter.setSelectedIndex(1);
	} else {
	    this.langListForFilter.setSelectedIndex(2);
	}
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_LANG, lb));
	main.setWidget(row, 0, lb);
	main.setWidget(row, 1, this.langListForFilter);
	main.getFlexCellFormatter().addStyleName(row, 0, "formlabel");
	this.langListForFilter.addStyleName("forminput");
	this.langListForFilter.addChangeHandler(new ChangeHandler() {

	    @Override
	    public void onChange(ChangeEvent event) {
		updateCategories();
	    }
	});
	row++;

	String lang = SettingsPopup.this.langListForFilter.getItemText(SettingsPopup.this.langListForFilter.getSelectedIndex());
	this.categoryListForFilter = new ListBox();
	this.categoryListForFilter.addItem("", "-1");
	for (Category c : this.parent.getInitData().getCategories()) {
	    if (lang.equals("") || c.getLanguage().equals(lang)) {
		this.categoryListForFilter.addItem(c.getLabel(), c.getId().toString());
	    }
	}
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_CATEGORY, lb));
	main.setWidget(row, 1, this.categoryListForFilter);
	main.setWidget(row, 0, lb);
	main.getFlexCellFormatter().addStyleName(row, 0, "formlabel");
	this.categoryListForFilter.addStyleName("forminput");
	this.categoryListForFilter.addChangeHandler(new ChangeHandler() {

	    @Override
	    public void onChange(ChangeEvent event) {
		updateFeeds();
	    }
	});
	row++;

	String cat = SettingsPopup.this.categoryListForFilter.getValue(SettingsPopup.this.categoryListForFilter.getSelectedIndex());
	this.feedList = new ListBox();
	for (Feed c : this.parent.feeds.values()) {
	    if ((lang.equals("") || lang.equals(c.getLanguage())) && (cat.equals("-1") || cat.equals(c.getCategory().toString()))) {
		this.feedList.addItem(c.getLabel(), c.getId().toString());
	    }
	}

	this.feedList.addChangeHandler(this);

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_ADD_CHANEL, lb));
	main.setWidget(row, 0, lb);
	main.setWidget(row, 1, this.feedList);
	main.getFlexCellFormatter().addStyleName(row, 0, "formlabel");
	this.feedList.addStyleName("forminput");
	row++;

	this.usercategoryList = new ListBox();
	this.usercategoryList.addItem(UserCategory.DEF_TAB, "-1");
	if (this.parent.getSelectedUserCaegory().equals(UserCategory.DEF_TAB)) {
	    this.usercategoryList.setSelectedIndex(0);
	}
	int i = 1;
	for (UserCategory c : this.parent.getInitData().getUsercategories()) {
	    this.usercategoryList.addItem(c.getLabel(), c.getId().toString());
	    if (this.parent.getSelectedUserCaegory().equals(c.getLabel())) {
		this.usercategoryList.setSelectedIndex(i);
	    }
	    i++;
	}
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_TAB, lb));
	main.setWidget(row, 0, lb);
	main.setWidget(row, 1, this.usercategoryList);
	main.getFlexCellFormatter().addStyleName(row, 0, "formlabel");
	this.usercategoryList.addStyleName("forminput");
	row++;

	Button addBt = new Button();
	addBt.addStyleName("button");
	addBt.setText(Dictionary.getEntry(Dictionary.BUTTON_ADD_FEED, addBt));
	addBt.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		Long catId = Long.parseLong(SettingsPopup.this.feedList.getValue(SettingsPopup.this.feedList.getSelectedIndex()));
		if (hasThisFeed(catId)) {
		    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_OWNED_FEED, null));
		} else {
		    Position p = SettingsPopup.this.parent.getFreePosition(null);
		    if (p == null) {
			Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_NO_FREECELL, null));
			return;
		    }
		    UserFeed uc = new UserFeed();
		    Long category = Long.parseLong(SettingsPopup.this.usercategoryList.getValue(SettingsPopup.this.usercategoryList.getSelectedIndex()));
		    if (category.equals(new Long(-1))) {
			category = null;
		    }
		    uc.setUsercategory(category);
		    uc.setId(Feeds.getNextId());
		    uc.setX(p.getRow());
		    uc.setY(p.getCol());
		    uc.setFeed(catId);
		    SettingsPopup.this.parent.addUserFeed(uc);
		}
	    }
	});
	main.setWidget(row, 1, addBt);
	row++;

	Button saveBt = new Button();
	saveBt.addStyleName("button");
	saveBt.setText(Dictionary.getEntry(Dictionary.BUTTON_SAVE_STATE, saveBt));
	saveBt.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		SettingsPopup.this.parent.save();
	    }
	});
	main.setWidget(row, 1, saveBt);

	main.addStyleName("border");
	main.addStyleName("form");

	return main;
    }

    private Widget getNewFeedSettingsPanel() {
	FlexTable main = new FlexTable();

	Label lb = new Label();
	lb.addStyleName("formtitle");
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_OFFER_CHANEL, lb));
	main.setWidget(0, 0, lb);
	main.getFlexCellFormatter().setColSpan(0, 0, 2);

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_CHANEL_name, lb));
	main.setWidget(1, 0, lb);
	main.setWidget(1, 1, this.newFeedName);

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_CHANEL_URL, lb));
	main.setWidget(2, 0, lb);
	main.setWidget(2, 1, this.newFeedUrl);

	this.langList = new ListBox();
	this.langList.addItem(UserInfo.LANG_EN);
	this.langList.addItem(UserInfo.LANG_HU);
	if (Feeds.getLanguage().equals(UserInfo.LANG_EN)) {
	    this.langList.setSelectedIndex(0);
	} else {
	    this.langList.setSelectedIndex(1);
	}
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_LANG, lb));
	main.setWidget(3, 0, lb);
	main.setWidget(3, 1, this.langList);
	this.langList.addChangeHandler(new ChangeHandler() {

	    @Override
	    public void onChange(ChangeEvent event) {
		SettingsPopup.this.categoryList.clear();
		String lang = SettingsPopup.this.langList.getItemText(SettingsPopup.this.langList.getSelectedIndex());
		for (Category c : SettingsPopup.this.parent.getInitData().getCategories()) {
		    if (c.getLanguage().equals(lang)) {
			SettingsPopup.this.categoryList.addItem(c.getLabel(), c.getId().toString());
		    }
		}
	    }
	});

	String lang = this.langList.getItemText(this.langList.getSelectedIndex());

	this.categoryList = new ListBox();
	for (Category c : this.parent.getInitData().getCategories()) {
	    if (c.getLanguage().equals(lang)) {
		this.categoryList.addItem(c.getLabel(), c.getId().toString());
	    }
	}

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_CATEGORY, lb));
	main.setWidget(4, 1, this.categoryList);
	main.setWidget(4, 0, lb);

	this.newFeedDesc = new TextArea();
	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_DESCRIPTION, lb));

	main.setWidget(5, 0, lb);
	main.setWidget(6, 0, this.newFeedDesc);
	main.getFlexCellFormatter().setColSpan(6, 0, 2);

	Button addBt = new Button();
	addBt.addStyleName("button");
	addBt.setText(Dictionary.getEntry(Dictionary.BUTTON_OFFER, addBt));
	addBt.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		offer();
	    }
	});
	main.setWidget(7, 1, addBt);

	main.addStyleName("border");
	main.addStyleName("form");
	main.getFlexCellFormatter().addStyleName(1, 0, "formlabel");
	main.getFlexCellFormatter().addStyleName(2, 0, "formlabel");
	main.getFlexCellFormatter().addStyleName(3, 0, "formlabel");
	main.getFlexCellFormatter().addStyleName(4, 0, "formlabel");
	main.getFlexCellFormatter().addStyleName(5, 0, "formlabel");
	this.newFeedName.addStyleName("forminput");
	this.newFeedUrl.addStyleName("forminput");
	this.categoryList.addStyleName("forminput");
	this.langList.addStyleName("forminput");
	this.newFeedDesc.addStyleName("forminput");
	this.newFeedDesc.addStyleName("textarea");
	return main;
    }

    private Widget getUserCategorySettingsPanel() {
	FlexTable main = new FlexTable();

	Label lb = new Label();
	lb.addStyleName("formtitle");
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_ADD_TAB, lb));
	main.setWidget(0, 0, lb);
	main.getFlexCellFormatter().setColSpan(0, 0, 2);

	final TextBox newCatNameTb = new TextBox();

	lb = new Label();
	lb.setText(Dictionary.getEntry(Dictionary.LABEL_TAB_NAME, lb));

	main.setWidget(1, 0, lb);
	main.setWidget(1, 1, newCatNameTb);

	Button addBt = new Button();
	addBt.addStyleName("button");
	addBt.setText(Dictionary.getEntry(Dictionary.BUTTON_ADD_TAB, addBt));
	addBt.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		if (newCatNameTb.getValue() == null || newCatNameTb.getValue().length() == 0) {
		    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_TABNAME_REQUIRED, null));
		    return;
		}
		if (hasThisUserCategory(newCatNameTb.getValue())) {
		    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_EXISTED_TAB, null));
		    return;
		}
		UserCategory c = new UserCategory();
		c.setLabel(newCatNameTb.getValue());

		SettingsPopup.this.parent.service.newUserCategory(c, new AsyncCallback<UserCategory>() {

		    @Override
		    public void onFailure(Throwable caught) {
			Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_COMM_ERROR, null));
		    }

		    @Override
		    public void onSuccess(UserCategory result) {
			if (result == null) {
			    Window.alert(Dictionary.getEntry(Dictionary.MESSAGE_COMM_ERROR, null));
			    return;
			}
			SettingsPopup.this.parent.getInitData().getUsercategories().add(result);
			SettingsPopup.this.usercategoryList.addItem(result.getLabel(), result.getId().toString());
			SettingsPopup.this.usercategoryList.setSelectedIndex(SettingsPopup.this.categoryList.getItemCount() - 1);
			newCatNameTb.setValue(null);
		    }
		});
	    }
	});
	main.setWidget(2, 1, addBt);
	main.addStyleName("border");
	main.addStyleName("form");
	main.getFlexCellFormatter().addStyleName(1, 0, "formlabel");
	newCatNameTb.addStyleName("forminput");
	return main;
    }

    private void updateCategories() {
	String lang = SettingsPopup.this.langListForFilter.getItemText(SettingsPopup.this.langListForFilter.getSelectedIndex());
	this.categoryListForFilter.clear();
	this.categoryListForFilter.addItem("", "-1");
	for (Category c : this.parent.getInitData().getCategories()) {
	    if (lang.equals("") || c.getLanguage().equals(lang)) {
		this.categoryListForFilter.addItem(c.getLabel(), c.getId().toString());
	    }
	}
	updateFeeds();
    }

    private void updateFeeds() {
	String lang = SettingsPopup.this.langListForFilter.getItemText(SettingsPopup.this.langListForFilter.getSelectedIndex());
	String cat = SettingsPopup.this.categoryListForFilter.getValue(SettingsPopup.this.categoryListForFilter.getSelectedIndex());
	this.feedList.clear();
	for (Feed c : this.parent.feeds.values()) {
	    if ((lang.equals("") || lang.equals(c.getLanguage())) && (cat.equals("-1") || cat.equals(c.getCategory().toString()))) {
		this.feedList.addItem(c.getLabel(), c.getId().toString());
	    }
	}
    }
}
